package com.micro.modual.async.completion.manager;

import com.micro.core.exception.BizException;
import com.micro.modual.async.completion.enums.CompletionRuleFlag;
import com.micro.modual.async.completion.executor.CompletionRuleExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * <h1>异步实现规则执行管理器</h1>
 * @author LevelCoder
 * @version V1.0.0
 * @email LevelCoder@126.com
 * @date 2020/5/6
 */
@Slf4j
@Component
@SuppressWarnings("all")
public class CompletionExecuteManager<T> implements BeanPostProcessor {

    /**
     * 定义规则执行器映射
     */
    private Map<CompletionRuleFlag,CompletionRuleExecutor> executorIndex = new HashMap<>(CompletionRuleFlag.values().length);

    /**
     * 优惠券结算规则计算入口:需保证传递进来的优惠券的个数 >=1
     * @param settlementInfo
     * @return
     * @throws CouponException
     */
    public void computeRule(String asyncRuleType,T t) throws BizException {
        CompletionRuleFlag asyncRuleFlag = CompletionRuleFlag.of(asyncRuleType);
        switch (asyncRuleFlag){
            case ASYNC_COUPON_CODE:
                executorIndex.get(CompletionRuleFlag.ASYNC_COUPON_CODE).computeRule(t);
                break;
            case ASYNC_DEFAULT_USER_INFO:
                executorIndex.get(CompletionRuleFlag.ASYNC_DEFAULT_USER_INFO).computeRule(t);
                break;
            case ASYNC_REMOVE_GOODS_SKU:
                executorIndex.get(CompletionRuleFlag.ASYNC_REMOVE_GOODS_SKU).computeRule(t);
                break;
        }
    }


    /**
     * 在bean初始化之前进行执行(before)
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Nullable
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //如果当前bean不是AsyncRuleExecutor的实现则直接返回bean
        if(!(bean instanceof CompletionRuleExecutor)){
            return bean;
        }
        //把bean强转为RuleExecutor
        CompletionRuleExecutor ruleExecutor = (CompletionRuleExecutor) bean;
        CompletionRuleFlag ruleFlag = ruleExecutor.ruleConfig();
        //如果ruleFlag已经注册了则抛出异常
        if(executorIndex.containsKey(ruleFlag)){
            throw new IllegalStateException("There is already an executor fro rule flag" + ruleFlag);
        }
        log.info("Load executor {} for rule flag {}",ruleExecutor.getClass(),ruleFlag);
        executorIndex.put(ruleFlag,ruleExecutor);
        return null;
    }

    /**
     * 在bean初始化之后进行执行(after)
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Nullable
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}
